<template>
  <div class="clip-box">
    <div class="canvas-box" :style="getStyle" @mousedown="startFunc" @mouseup="moveFunc">
      <canvas :width="state.CW" :height="state.CH" ref="canvas"></canvas>
      <div class="mark" v-show="state.isMark"  :style="{width:state.MW+'px',height:state.MH+'px',left:state.ML+'px',top:state.MT+'px'}"></div>
    </div>
    <div class="btn-box">
      <input type="file" accept="image/*" class="file" ref="file" @change="changeFunc"/>
      <button class="myBtn" @click="clickFunc">选择图片</button>
      <button class="myBtn" @click="scaleFunc(1)">放大</button>
      <button class="myBtn" @click="scaleFunc(0)">缩小</button>
      <button class="myBtn" @click="saveFunc">保存</button>
    </div>
    
  </div>
</template>


<script setup>
import { reactive,ref,defineEmits } from "vue";
import { computed, watch } from "vue";

/* 
步骤：
1.我们需要准备一些数据：画布的大小和位置、上传图片的大小和位置、是否显示Mark
2.上传图片：选中图片，把其绘制到画布中
3.实现图片的拖拽Touch：重新绘制图片所在的位置
4.实现图片的放大和缩小，重新绘制图片的大小
5.保存图片的时候：把遮罩层选中的部分（像素）最后生成一张新的图片
*/

let winW=document.documentElement.clientWidth;
let font=parseInt(document.documentElement.style.fontSize)
let cansW=winW*0.5
let markW=cansW*0.7
let state=reactive({
  //画布大小
  CW:cansW,
  CH:cansW,
  //mark大小和位置
  MW:markW,
  MH:markW,
  ML:(cansW-markW)/2,
  MT:(cansW-markW)/2,
  //上传图片的大小和位置
  IW:0,
  IH:0,
  IL:0,
  IT:0,
  //是否显示mark
  isMark:false,
})
watch(() => state.isMark, (newval) => {
  console.log(newval)
})
let canvas=ref(null)
let file=ref(null)
let IMAGE;
const emit=defineEmits(["saveImage"])//注册方法
let CTX;//画布
let startX,startY,changeX,changeY;

//样式
let getStyle=computed(()=>{
  return `width: ${state.CW+10}px; height: ${state.CH+10}px;`
})

const clickFunc=()=>{
  //触发file选择文件
  file.value.click()
}

//上传裁剪的图片
const changeFunc=(e)=>{
  // console.log(e)
  //选择了新的图片
  state.isMark = true;
/*   let { ctx: that } = getCurrentInstance()
	that.$forceUpdate()
  console.log(state) */
  console.log(e);
  let file=e.target.files[0]
  if(!file) return;
  //先基于FileReader进行文件读取
  let fileExample = new FileReader();
  fileExample.readAsDataURL(file);
  fileExample.onload=ev=>{
    //创建新图片
    IMAGE = new Image();
    IMAGE.src=ev.target.result;
    IMAGE.onload=_=>{
      console.log(IMAGE.width);
      state.IW=IMAGE.width;
      state.IH=IMAGE.height;
      //重新按照比列计算宽高
      let n=1
      if(state.IW>state.IH){
        n=state.IW/state.CW//缩放比例
        state.IW=state.CW
        state.IH=state.IH/n
      }else{
        n=state.IH/state.CH
        state.IH=state.CH
        state.IW=state.IW/n
      }
      state.IL=(state.CW-state.IW)/2
      state.IT=(state.CH-state.IH)/2
      //绘制图片
      drawImage()
    }
  }
}
//绘制图片
function drawImage(){
  console.log(canvas)
  //创建2D渲染画布
  CTX=canvas.value.getContext("2d")
  //清空画布
  CTX.clearRect(0,0,state.CW,state.CH)
  //绘制图片
  CTX.drawImage(IMAGE,state.IL,state.IT,state.IW,state.IH)
}

//放大、缩小
function scaleFunc(flag){
  if(!IMAGE) return;
  //n为宽高比
  let n=state.IW/state.IH,
      n1=20,//设定每次宽变化改变20像素
      n2=n1/n;//高变化的像素
  if(flag){
    state.IW+=n1;
    state.IH+=n2
    }else{
    state.IW-=n1;
    state.IH-=n2;
  }
  drawImage();//重新绘制
}

//拖拽图片
function startFunc(ev){
  //移动端用touchstart、touchend
  console.log(ev)
  //按下的时候获取手指的坐标
  // let point=ev.changedTouches[0];
  /* startX=point.clientX
  startY=point.clientY */
  startX=ev.clientX
  startY=ev.clientY
}
function moveFunc(ev) {
  // let point=ev.changedTouches[0];
  /* changeX=point.clientX-startX
  changeY=point.clientY-startY */
  changeX=ev.clientX-startX
  changeY=ev.clientY-startY
  //处理偏移
  if(Math.abs(changeX)>10||Math.abs(changeY)>10){
    state.IL+=changeX;
    state.IT+=changeY;
    drawImage()
    /* startX=point.clientX
    startY=point.clientY */
    startX=ev.clientX
    startY=ev.clientY
  }
}

//保存裁剪后的图片
const saveFunc=()=>{
  if(!IMAGE) return
  //获取指定区域的像素信息
  let imageData=CTX.getImageData(state.ML,state.MT,state.MW,state.MH)
  //创建新的画布
  let canvas2=document.createElement("canvas"),
      canvas2CTX=canvas2.getContext("2d");
  canvas2.width=state.MW;
  canvas2.height=state.MH;
  //把像素点信息放到画布中
  canvas2CTX.putImageData(imageData,0,0,0,0,state.MW,state.MH)
  // console.log(canvas2.toDataURL("image/png"))//拿到图片信息
  let base64 = canvas2.toDataURL("image/png")
  emit("saveImage",base64)
}

</script>





<style scoped>
.clip-box{
  /* padding: 0.4rem; */

}
.canvas-box{
  overflow: hidden;
  width: 3rem;
  position: relative;
  margin: 0 auto;
}
canvas{
 /*  width: 3rem;
  height: 3rem;*/
  
  border: 0.01rem solid pink;
  box-sizing: border-box;
}
.mark{
  box-sizing: border-box;
  position: absolute;
  /* top: 50%;
  left: 50%;
  transform: translate(-50%,-50%); */
  /* top: 50%;
  left: 50%;
  margin-top: -100px;
  margin-left: -100px; */
 /*  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  margin: auto; */
  z-index: 20;
/*   width: 2rem;
  height: 2rem; */
  border: 0.01rem dashed lightcoral;
  background: rgba(0, 0, 0, 0.2);
}
.myBtn{
  border: none;
  margin: 0.1rem;
}
.file{
  display: none;
}
</style>